/**
 * 
 */
package com.desksoft.ecommerce.handler.filter;

import java.io.IOException;
import java.util.concurrent.Semaphore;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.desksoft.ecommerce.constants.ISession;

/***************************************
 * 版权所有：杭州迪科软件 保留所有权利
 * 创建日期: 
 * 创建作者：yejw
 * 文件名称：
 * 版本：
 * 功能：
 * 最后修改时间：
 * 修改记录：
 *****************************************/
public class SessionUserFilter implements Filter, ISession{
	
	/**
     * Logger for this class
     */
	protected static final Log logger = LogFactory.getLog(SessionUserFilter.class);

    /**
     * 初始化session锁
     */
    protected Semaphore lock = new Semaphore(1);
    
    protected String urlToRedirectTo;

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {
		
	}

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(ServletRequest servletRequest,
            ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
		
		final HttpServletRequest request = (HttpServletRequest) servletRequest;
		final HttpServletResponse response = (HttpServletResponse) servletResponse;
        final HttpSession session = request.getSession();
        
		boolean needRelease = false;
		if (session.getAttribute(SESSION_USER_KEY) == null) {
			try {
            	needRelease = true;
                lock.acquire();
                // 锁释放后再次判断
				if (session.getAttribute(SESSION_USER_KEY) == null) {
					
					//根据请求头判断是否为AJAX请求。
			        String ajax = request.getHeader("X-Requested-With");
			        if (StringUtils.isNotBlank(ajax)){
			        	//不进行重定向，直接返回需要登录。
			        	logger.info("ajax request can not redirect to server.");
			        	response.setHeader("X-cas", "1");
			        	response.setStatus(401);
			        	response.getOutputStream().close();
			        	return;
			        }
					
					response.sendRedirect(String.format("%s/%s", 
							request.getContextPath(), urlToRedirectTo));
				}
            } catch (Exception e) {
                e.printStackTrace();
                return;
            } finally {
				if (needRelease) {
					lock.release();
				}
            }
        }
		
		if (!this.afterProcess(servletRequest, servletResponse, chain)) {
			return;
		}

        chain.doFilter(servletRequest, servletResponse);
	}

	/**
	 * 后续处理
	 * 
	 * @param servletRequest
	 * @param response
	 * @param chain
	 * @param userVo
	 * @return
	 */
	protected boolean afterProcess(ServletRequest servletRequest, 
			ServletResponse response, FilterChain chain){
    	return true;
    }

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(FilterConfig config) throws ServletException {
		urlToRedirectTo = config.getInitParameter("serverLoginUrl");
	}
	
	protected void writeFailResult(ServletResponse response, String msg) throws IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().write(msg);
	}

}
